package com.fr.web.core.service;

import com.fr.base.ConcurrentHashMap;
import com.fr.base.FRContext;
import com.fr.base.Inter;
import com.fr.base.StringUtils;
import com.fr.base.core.BaseCoreUtils;
import com.fr.base.core.ComparatorUtils;
import com.fr.base.core.FRCoreContext;
import com.fr.base.core.RSADecode;
import com.fr.base.core.html.Tag;
import com.fr.base.core.html.TextHtml;
import com.fr.base.core.json.JSONArray;
import com.fr.base.core.json.JSONObject;
import com.fr.base.core.util.TemplateUtils;
import com.fr.base.file.ClusterConfigManager;
import com.fr.base.file.ConfigManager;
import com.fr.util.Consts;
import com.fr.web.EmbeddedTplReportlet;
import com.fr.web.ReportletException;
import com.fr.web.Weblet;
import com.fr.web.cache.WebletFactory;
import com.fr.web.cluster.ClusterService;
import com.fr.web.core.SessionIDInfor;
import com.fr.web.core.ShowWorkBookPolicy.Policy4Page;
import com.fr.web.core.WebUtils;
import java.io.ByteArrayOutputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class SessionDealWith
{
  private static boolean registed = false;
  private static Random sessionIDRandom = null;
  private static int maxAddressCount = 5;
  private static final long __init_time__ = System.currentTimeMillis();
  public static final Object SESSION_ID_MAP_LOCK;
  public static final Object ADDRESS_MANAGER_LOCK;
  private static Map sessionIDMap;
  private static ConcurrentHashMap addressManager;
  private static Comparator keysTimeCompartor;

  public static String getOrGenerateSessionID(HttpServletRequest paramHttpServletRequest, HttpServletResponse paramHttpServletResponse)
    throws Exception
  {
    String str = WebUtils.getHTTPRequestParameter(paramHttpServletRequest, "sessionID");
    if (str == null)
      str = generateSessionID(paramHttpServletRequest, paramHttpServletResponse, WebletFactory.createWebletByRequest(paramHttpServletRequest));
    return str;
  }

  public static String generateSessionID(HttpServletRequest paramHttpServletRequest, HttpServletResponse paramHttpServletResponse, Weblet paramWeblet)
    throws Exception
  {
    if (paramWeblet == null)
      throw new ReportletException("Need to specify parameter \"reportlet\" or \"resultlet\".");
    if (generateSessionID_isPromptRegisted(paramHttpServletRequest))
      paramWeblet = WebletFactory.createEmbeddedResultlet("/com/fr/web/console/lic.xml", new ShowWorkBookPolicy.Policy4Page());
    String str = getIpAddr(paramHttpServletRequest);
    Map localMap = WebUtils.parameters4SessionIDInfor(paramHttpServletRequest);
    generateSessionID_dealWithOverFlow(paramHttpServletRequest, paramHttpServletResponse);
    SessionIDInfor localSessionIDInfor = null;
    if (paramWeblet != null)
    {
      if (paramWeblet instanceof EmbeddedTplReportlet)
      {
        EmbeddedTplReportlet localEmbeddedTplReportlet = (EmbeddedTplReportlet)paramWeblet;
        localMap.putAll(localEmbeddedTplReportlet.getParameterMap());
      }
      localSessionIDInfor = paramWeblet.createSessionIDInfor(paramHttpServletRequest, str, localMap);
    }
    return generateSessionID_addSessionIDInfor(localSessionIDInfor, str);
  }

  private static String generateSessionID_addSessionIDInfor(SessionIDInfor paramSessionIDInfor, String paramString)
    throws Exception
  {
    String str = addSessionIDInfor(paramSessionIDInfor);
    Object localObject = new HashSet();
    Set localSet = (Set)addressManager.putIfAbsent(paramString, localObject);
    localObject = (localSet == null) ? localObject : localSet;
    ((Set)localObject).add(str);
    return ((String)str);
  }

  private static void generateSessionID_dealWithOverFlow(HttpServletRequest paramHttpServletRequest, HttpServletResponse paramHttpServletResponse)
    throws Exception
  {
    if (maxAddressCount < addressManager.size())
      try
      {
        WebUtils.overflow(paramHttpServletRequest, paramHttpServletResponse, addressManager.keySet());
      }
      catch (Exception localException)
      {
        throw new Exception(Inter.getLocText("EX-IP_Address_Overflow"));
      }
  }

  private static boolean generateSessionID_isPromptRegisted(HttpServletRequest paramHttpServletRequest)
  {
    if ((registed) || (isLocalHost(paramHttpServletRequest)))
      return false;
    return (Math.random() * 10.0D <= (System.currentTimeMillis() - __init_time__) / 3600000L / 24L + 1L);
  }

  public static void writeRegistionDiv(HttpServletRequest paramHttpServletRequest, PrintWriter paramPrintWriter)
  {
    if (generateSessionID_isPromptRegisted(paramHttpServletRequest))
    {
      Tag localTag = new Tag("div");
      localTag.css("left", "2px");
      localTag.css("bottom", "36px");
      localTag.css("font", "normal bolder 10pt Arial");
      localTag.css("position", "absolute");
      localTag.sub(new TextHtml("<a href='" + Consts.WEBSITE_URL + "' target='_blank'>" + Inter.getLocText("Registration-Please_Purchase") + Consts.APP_NAME + Inter.getLocText("Registration-Enterprise_Edition") + "</a>---" + "<a href='" + WebUtils.createServletURL(paramHttpServletRequest) + "?op=console_reg' target='_blank'>" + Inter.getLocText("Registration") + "</a>"));
      localTag.writeHtml(paramPrintWriter);
    }
  }

  protected static String addSessionIDInfor(SessionIDInfor paramSessionIDInfor)
    throws Exception
  {
    String str = null;
    synchronized (SESSION_ID_MAP_LOCK)
    {
      removeExtraSession();
      if (paramSessionIDInfor != null)
      {
        str = createSessionID();
        sessionIDMap.put(str, paramSessionIDInfor);
        paramSessionIDInfor.setSessionID(str);
      }
    }
    return str;
  }

  protected static String createSessionID()
    throws Exception
  {
    for (String str = randomSessionID(); sessionIDMap.containsKey(str); str = randomSessionID());
    return str;
  }

  private static String getIpAddr(HttpServletRequest paramHttpServletRequest)
  {
    String str = paramHttpServletRequest.getHeader("x-forwarded-for");
    if ((StringUtils.isEmpty(str)) || ("unknown".equalsIgnoreCase(str)))
      str = paramHttpServletRequest.getHeader("Proxy-Client-IP");
    if ((StringUtils.isEmpty(str)) || ("unknown".equalsIgnoreCase(str)))
      str = paramHttpServletRequest.getHeader("WL-Proxy-Client-IP");
    if ((StringUtils.isEmpty(str)) || ("unknown".equalsIgnoreCase(str)))
      str = paramHttpServletRequest.getRemoteAddr();
    return str;
  }

  public static String getUserIp(HttpServletRequest paramHttpServletRequest)
  {
    return getIpAddr(paramHttpServletRequest);
  }

  private static boolean isLocalHost(HttpServletRequest paramHttpServletRequest)
  {
    String str = getIpAddr(paramHttpServletRequest);
    return (("127.0.0.1".equals(str)) || ("localhost".equals(str)) || ("0:0:0:0:0:0:0:1".equals(str)));
  }

  public static void removeExtraSession()
  {
    SessionIDInfor[] arrayOfSessionIDInfor;
    int j;
    int i = FRContext.getConfigManager().getConcurrency();
    if ((i >= 0) && (sessionIDMap.size() > i))
    {
      arrayOfSessionIDInfor = (SessionIDInfor[])sessionIDMap.values().toArray(new SessionIDInfor[0]);
      Arrays.sort(arrayOfSessionIDInfor, keysTimeCompartor);
      for (j = arrayOfSessionIDInfor.length - i - 1; j >= 0; --j)
        closeSession(arrayOfSessionIDInfor[j].getSessionID());
    }
  }

  private static String randomSessionID()
  {
    if (sessionIDRandom == null)
      sessionIDRandom = new Random();
    String str = System.currentTimeMillis() + "_" + sessionIDRandom.nextInt(5000);
    if (FRContext.getClusterConfigManager().isUseCluster())
    {
      ClusterService localClusterService = FRContext.getClusterConfigManager().getSelfService();
      if ((localClusterService != null) && (localClusterService.getServiceName() != null))
        return localClusterService.getServiceName() + "_" + str;
    }
    return str;
  }

  public static void closeSession(Object paramObject)
  {
    SessionIDInfor localSessionIDInfor = (SessionIDInfor)sessionIDMap.remove(paramObject);
    if (localSessionIDInfor != null)
    {
      localSessionIDInfor.release();
      String str = localSessionIDInfor.getRemoteAddress();
      synchronized (ADDRESS_MANAGER_LOCK)
      {
        Set localSet = (Set)addressManager.get(str);
        if (localSet != null)
          localSet.remove(paramObject);
        if ((localSet == null) || (localSet.size() == 0))
          addressManager.remove(str);
      }
    }
    FRContext.getLogger().log(Level.INFO, "Close Session: " + paramObject);
  }

  public static void writeSessionTimeout(HttpServletRequest paramHttpServletRequest, HttpServletResponse paramHttpServletResponse)
    throws Exception
  {
    TemplateUtils.dealWithTemplate("/com/fr/web/core/session.html", paramHttpServletResponse, WebUtils.createTemplateMap(paramHttpServletRequest));
  }

  public static void responseSessionID(HttpServletRequest paramHttpServletRequest, HttpServletResponse paramHttpServletResponse)
    throws Exception
  {
    String str = getOrGenerateSessionID(paramHttpServletRequest, paramHttpServletResponse);
    if ((str != null) && (!(sessionIDMap.containsKey(str))))
      str = null;
    if (str != null)
    {
      PrintWriter localPrintWriter = WebUtils.createPrintWriter(paramHttpServletResponse);
      localPrintWriter.write(str);
      localPrintWriter.flush();
      localPrintWriter.close();
    }
  }

  public static SessionIDInfor getSessionIDInfor(String paramString)
  {
    if (StringUtils.isBlank(paramString))
      return null;
    SessionIDInfor localSessionIDInfor = (SessionIDInfor)sessionIDMap.get(paramString);
    if (localSessionIDInfor != null)
      localSessionIDInfor.updateTime();
    return localSessionIDInfor;
  }

  public static boolean hasSessionID(String paramString)
  {
    return sessionIDMap.containsKey(paramString);
  }

  public static void viewSessions(HttpServletRequest paramHttpServletRequest, HttpServletResponse paramHttpServletResponse)
    throws Exception
  {
    JSONArray localJSONArray = new JSONArray();
    Iterator localIterator = sessionIDMap.values().iterator();
    while (true)
    {
      do
      {
        if (!(localIterator.hasNext()))
          break label111;
        localObject = localIterator.next();
      }
      while (!(localObject instanceof SessionIDInfor));
      SessionIDInfor localSessionIDInfor = (SessionIDInfor)localObject;
      localJSONArray.put(new JSONObject().put("sessionID", localSessionIDInfor.getSessionID()).put("name", localSessionIDInfor.getReportletTitle()).put("ip", localSessionIDInfor.getRemoteAddress()).put("user", localSessionIDInfor.getParameterValue("fr_username")));
    }
    label111: Object localObject = WebUtils.createPrintWriter(paramHttpServletResponse);
    ((PrintWriter)localObject).print(localJSONArray);
    ((PrintWriter)localObject).flush();
    ((PrintWriter)localObject).close();
  }

  static
  {
    byte[] arrayOfByte = FRCoreContext.getBytes();
    ByteArrayOutputStream localByteArrayOutputStream = new ByteArrayOutputStream();
    try
    {
      RSADecode.decode(arrayOfByte, localByteArrayOutputStream);
    }
    catch (Exception localException1)
    {
    }
    try
    {
      JSONObject localJSONObject = new JSONObject(new String(localByteArrayOutputStream.toByteArray(), "UTF-8"));
      if ((localJSONObject.getLong("deadline") > Calendar.getInstance().getTimeInMillis()) && (localJSONObject.has("version")) && (ComparatorUtils.equals(Consts.VERSION, localJSONObject.getString("version"))) && (((localJSONObject.getLong("deadline") - Calendar.getInstance().getTimeInMillis() < new Long("3153600000").longValue()) || ((localJSONObject.has("macaddress")) && (BaseCoreUtils.getMacAddresses().contains(localJSONObject.getString("macaddress")))))))
      {
        registed = true;
        int i = 0;
        if (localJSONObject.has("concurrency"))
          i = localJSONObject.getInt("concurrency");
        maxAddressCount = (i <= 0) ? 2147483647 : i;
      }
    }
    catch (Exception localException2)
    {
    }
    SESSION_ID_MAP_LOCK = new Object();
    ADDRESS_MANAGER_LOCK = new Object();
    sessionIDMap = new Hashtable();
    addressManager = new ConcurrentHashMap();
    keysTimeCompartor = new Comparator()
    {
      public int compare(Object paramObject1, Object paramObject2)
      {
        SessionIDInfor localSessionIDInfor1 = (SessionIDInfor)paramObject1;
        SessionIDInfor localSessionIDInfor2 = (SessionIDInfor)paramObject2;
        long l1 = localSessionIDInfor1.getLastTime();
        long l2 = localSessionIDInfor2.getLastTime();
        if (l1 < l2)
          return -1;
        if (l1 > l2)
          return 1;
        return 0;
      }
    };
  }
}